<template>
  <!--图片批量上传-->
  <transition name="scale" appear>
    <el-dialog
      v-if="customMultiImg.visible"
      title="多图片上传"
      :visible.sync="customMultiImg.visible"
      append-to-body
      show-close
      top="55px"
      custom-class="tinymce"
      :before-close="resetCustomMultiImg"
      :close-on-press-escape="false"
      width="1200px"
    >
      <div style="width: 100%">
        <input
          ref="file"
          type="file"
          style="display: none"
          accept="image/png, image/jpeg, image/gif, image/jpg"
          multiple="multiple"
          @change="onChangeFile"
        />
        <div class="multi__header">
          <div class="header__left" @click.stop="onClearFileList">清空列表</div>
          <div class="header__right">
            <el-button type="primary" icon="el-icon-circle-plus-outline" @click.stop="onClickFile">添加文件</el-button>
            <el-button type="primary" :disabled="_multiImgDisabled" icon="el-icon-upload2" @click.stop="onUploadFileAll"
              >全部上传</el-button
            >
          </div>
        </div>
        <div class="multi__body">
          <vue-scroll style="height: 475px" detect-resize keep-show>
            <section v-if="fileList.length">
              <transition-group name="scale" appear tag="ul" class="file__list">
                <li v-for="(item, index) in fileList" :key="index + 1">
                  <div class="overlay">
                    <i class="el-icon-zoom-in" @click.stop="onPreviewImg(item.blobUrl)"></i>
                    <i class="el-icon-delete" @click.stop="onDeleteImg(item, index)"></i>
                  </div>
                  <div class="picbox">
                    <img :src="item.blobUrl" />
                  </div>
                  <div class="namebox">
                    <span>{{ item.name }}</span>
                  </div>
                  <div v-if="item.status == 0" class="progress--no-upload">
                    <div>未上传</div>
                  </div>
                  <div v-else-if="item.status == 1" class="progress">
                    <i class="el-icon-loading"></i>
                    <div>
                      正在上传 <span>{{ item.percent >= 0 ? `${item.percent}%` : '' }}</span>
                    </div>
                  </div>
                  <div v-else-if="item.status == 2" class="progress--success">
                    <i class="el-icon-check"></i>
                  </div>
                  <div v-else-if="item.status == 3" class="progress progress--fail">
                    <i class="el-icon-circle-close"></i>
                    <div>上传失败</div>
                  </div>
                </li>
              </transition-group>
            </section>
            <section v-else class="file__list--empty">
              <i class="iconfont znz-icon-empty"></i>
              <div class="label">暂无数据</div>
            </section>
          </vue-scroll>
        </div>
        <div class="multi__footer">
          <div
            class="tinymce-button tinymce-button--cancel"
            style="color: white"
            @click.stop="customMultiImg.visible = false"
          >
            取消
          </div>
          <div class="tinymce-button" @click.stop="onSaveMultiImg">保存</div>
        </div>
      </div>
    </el-dialog>
  </transition>
</template>

<script>
import { uploadFileConfig, uploadFileName } from '../utils/common'
import axios from 'axios'
import { mapGetters, mapMutations } from 'vuex'
const $http = axios.create({
  timeout: 1000 * 30 // 请求超时时间 30s
})
export default {
  bucket: {
    // 图片项目模块
    type: String,
    default: 'advertise'
  },
  source: {
    type: String, // 图片分类
    default: 'major-case'
  },
  data() {
    return {
      customMultiImg: {
        visible: false
      },
      qiNiuUrl: uploadFileConfig.qiNiuUrl,
      fileList: [], // 文件
      html: '' // html代码
    }
  },

  computed: {
    ...mapGetters(['qiNiuConfigGetter']),

    _multiImgDisabled() {
      return this.fileList.every((item) => item.status == 2)
    }
  },

  methods: {
    ...mapMutations(['setLoading']),
    /**
     * 暴露出去  展示
     * */
    show() {
      this.customMultiImg.visible = true
    },

    /**
     * 暴露出去  关闭
     * */
    hide() {
      this.resetCustomMultiImg()
    },

    resetCustomMultiImg() {
      this.customMultiImg.visible = false
      this.fileList.forEach((item) => {
        window.URL.revokeObjectURL(item.blobUrl)
      })
      this.fileList = []
    },

    onClickFile() {
      this.$refs.file && this.$refs.file.click()
    },

    /**
     * 上传所有文件
     * */
    async onUploadFileAll() {
      if (this.fileList.every((item) => item.status == 2)) {
        this.$message.warning('暂无图片可上传')
        return
      }
      const getBlob = (url) => {
        return new Promise((resolve) => {
          const xhr = new XMLHttpRequest()
          xhr.open('GET', url, true)
          xhr.responseType = 'blob'
          xhr.onload = () => {
            if (xhr.status === 200) {
              resolve(xhr.response)
            }
          }
          xhr.send()
        })
      }

      const uploadImg = (blob, val) => {
        return new Promise((resolve) => {
          const formData = new FormData()
          formData.append('token', this.qiNiuConfigGetter.token)
          formData.append('file', blob)
          formData.append('key', uploadFileName(generateUuid() + '.png', this.source, this.bucket))
          val.status = 1 // 正在上传
          const config = {
            onUploadProgress: (progressEvent) => {
              val.percent = ((progressEvent.loaded / progressEvent.total) * 100) | 0
              console.log('进度加载中....', val.percent)
            },
            headers: {
              'Content-Type': 'multipart/form-data'
            }
          }
          $http
            .post(this.qiNiuUrl, formData, config)
            .then(async (res) => {
              console.log(res)
              if (val.percent >= 100) {
                val.status = 2 // 上传成功
              } else {
                val.status = 3 // 上传失败
              }
              // this.$emit('on-change-url', this.qiNiuConfigGetter.domain + res.data.key)
              resolve({
                code: 0,
                ...res
              })
            })
            .catch(async (err) => {
              await this.getQiNiuToken()
              val.status = 3 // 上传失败
              this.$message.warning('上传失败！请重新上传')
            })
            .finally(() => {
              this.setLoading(false)
            })
        })
      }

      for (let item of this.fileList) {
        if (item.status != 2) {
          // 非上传成功的文件 可以重新继续上传
          getBlob(item.blobUrl).then((blob) => {
            if (blob) {
              uploadImg(blob, item).then((res) => {
                if (res.code == 0) {
                  item.url = `${this.qiNiuConfigGetter.domain + res.data.key}`
                }
              })
            }
          })
          console.log('上传', this.html)
        }
      }
    },

    /**
     * 上传图片
     * */
    async onSaveMultiImg() {
      if (!this._multiImgDisabled) {
        this.$message.error('还有图片未上传，请上传或移除')
        return
      }
      let html = ''
      for (let item of this.fileList) {
        html += `<img src="${item.url}">`
      }
      this.$emit('on-multi-img-success', html)
    },

    /**
     * 清空文件列表
     * */
    onClearFileList() {
      this.fileList.forEach((item) => {
        window.URL.revokeObjectURL(item.blobUrl)
      })
      this.fileList = []
      this.$message.success('清除成功')
    },

    /**
     * 删除图片
     * */
    onDeleteImg(item, index) {
      this.fileList.splice(index, 1)
      window.URL.revokeObjectURL(item.blobUrl)
    },

    /**
     * 预览图片
     * */
    onPreviewImg(url) {
      console.log()
      this.$vuerApi({
        images: [url]
      })
    },

    onChangeFile(event) {
      if (!/\.(gif|jpg|jpeg|png|bmp|GIF|JPG|PNG)$/.test(event.target.value)) {
        this.$message.error('图片类型必须是.gif,jpeg,jpg,png,bmp中的一种')
        return
      }
      // reader.readAsArrayBuffer(file)
      console.log(event.target.files)
      for (let i in event.target.files) {
        const file = event.target.files[i]
        const blobUrl = window.URL.createObjectURL(file)
        this.fileList.push({
          percent: 0,
          status: 0, // 0、待上传 1 上传成功 2 上传中 3 上传失败
          name: file.name,
          blobUrl,
          url: ''
        })
      }
    }
  }
}
</script>

<style scoped lang="scss">
$--color-danger: $--color-danger;
.multi__header {
  margin: 0 10px;
  padding: 20px 0 12px;
  border-bottom: 1px solid #ccc;
  display: flex;
  justify-content: space-between;
  box-sizing: border-box;
  .header__left {
    height: 29px;
    line-height: 29px;
    padding: 0 16px;
    background-color: #f0f0f0;
    color: #223;
    border-radius: 3px;
    cursor: pointer;
    &:hover {
      opacity: 0.8;
    }
  }
  .header__right {
    ::v-deep .el-button + .el-button {
      margin-left: 2px;
    }
    ::v-deep .el-button {
      height: 29px;
      line-height: 29px;
      padding: 0 16px;
    }
  }
}
.multi__body {
  width: 100%;
  background: #fff;
  box-sizing: border-box;
  position: relative;
  height: 475px;
  .file__list--empty {
    height: 450px;
    display: flex;
    align-items: center;
    flex-direction: column;
    justify-content: center;
    i {
      font-size: 70px;
      color: #8c8c8c;
    }
    .label {
      font-size: 14px;
      color: #777;
    }
  }
  .file__list {
    display: grid;
    grid-gap: 10px;
    padding: 0 12px;
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
    padding-top: 10px;
    li {
      position: relative;
      display: block;
      vertical-align: top;
      padding: 5px 5px;
      border-radius: 5px;
      overflow: hidden;
      border: 1px dashed #ccc;
      &:hover {
        background-color: #ddd;
      }
      .progress {
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background-color: rgba(0, 0, 0, 0.5);
        transition: opacity 0.3s;
        position: absolute;
        z-index: 10;
        display: flex;
        align-items: center;
        justify-content: center;
        flex-direction: column;
        font-size: 12px;
        color: #fff;
        user-select: none;
        .el-icon-loading {
          display: inline-block;
          font-size: 22px;
          margin-bottom: 10px;
        }
        ::v-deep .el-progress {
          position: absolute;
          bottom: 0;
          left: 5px;
          width: calc(100% - 5px);
        }
      }
      .progress--success {
        position: absolute;
        right: -17px;
        top: -7px;
        width: 46px;
        height: 26px;
        background: #13ce66;
        text-align: center;
        transform: rotate(45deg);
        color: #fff;
        box-shadow: 0 1px 1px #ccc;
        i {
          display: inline-block;
          font-size: 12px;
          margin-top: 12px;
          transform: rotate(-45deg);
        }
      }
      .progress--no-upload {
        position: absolute;
        right: 0;
        top: 0;
        width: 46px;
        line-height: 24px;
        background: $--color-danger;
        padding: 0 5px;
        font-size: 12px;
        border-radius: 4px;
        text-align: center;
        color: #fff;
      }
      .progress--fail {
        z-index: 1;
        background-color: rgba(0, 0, 0, 0.2);
        .el-icon-circle-close {
          display: inline-block;
          font-size: 24px;
          margin-bottom: 10px;
        }
      }
      .overlay {
        position: absolute;
        width: 100%;
        height: 100%;
        left: 0;
        border-radius: 6px;
        top: 0;
        cursor: default;
        text-align: center;
        color: #fff;
        opacity: 0;
        font-size: 23px;
        background-color: rgba(0, 0, 0, 0.5);
        transition: opacity 0.3s;
        display: flex;
        align-items: center;
        justify-content: center;
        z-index: 10;
        &:hover {
          opacity: 0.8;
        }
        i {
          display: inline-block;
          cursor: pointer;
        }
        i + i {
          margin-left: 15px;
        }
      }
      .picbox {
        display: flex;
        flex: 0 0 auto;
        justify-content: center;
        overflow: hidden;
        position: relative;
        width: 100%;
        padding-top: 100%;
        align-items: center;
        img {
          object-fit: cover;
          display: block;
          max-width: 100%;
          max-height: 100%;
          position: absolute;
          top: 50%;
          left: 50%;
          transform: translateX(-50%) translateY(-50%);
        }
      }
      .namebox {
        font-size: 14px;
        line-height: 20px;
        max-height: 40px;
        overflow: hidden;
        padding: 5px 10px;
        text-align: center;
        display: flex;
        justify-content: center;
        align-items: flex-start;
        display: -webkit-box;
        -webkit-box-orient: vertical;
        -webkit-line-clamp: 2;
      }
    }
  }
}
.multi__footer {
  align-items: center;
  background-color: #fff;
  border-top: 1px solid #ccc;
  display: flex;
  justify-content: flex-end;
  padding: 15px 16px;
}
</style>
